package com.spaceobj.project.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.lang.RegexPool;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spaceobj.common.core.dto.SysUser;
import com.spaceobj.common.core.utils.ExceptionUtil;
import com.spaceobj.common.core.utils.RsaUtils;
import com.spaceobj.common.core.utils.SourceToTargetUtils;
import com.spaceobj.common.kafka.config.KafkaSender;
import com.spaceobj.common.kafka.constant.KafKaTopics;
import com.spaceobj.common.redis.constant.RedisKey;
import com.spaceobj.common.redis.service.RedisService;
import com.spaceobj.common.redis.service.RedissonService;
import com.spaceobj.project.bo.ProjectHelpBo;
import com.spaceobj.project.component.UserClient;
import com.spaceobj.project.mapper.ProjectHelpMapper;
import com.spaceobj.project.pojo.ProjectHelp;
import com.spaceobj.project.pojo.SysProject;
import com.spaceobj.project.service.ProjectHelpService;
import com.spaceobj.project.service.SysProjectService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author zhr_java@163.com
 * @date 2022/07/23 22:00
 */
@Service
@RefreshScope
public class ProjectHelpServiceImpl extends ServiceImpl<ProjectHelpMapper, ProjectHelp>
    implements ProjectHelpService {

  Logger logger = LoggerFactory.getLogger(ProjectHelpServiceImpl.class);

  @Autowired private RedisService redisService;

  @Autowired private RedissonService redissonService;

  @Autowired private ProjectHelpMapper projectHelpMapper;

  @Autowired private KafkaSender kafkaSender;

  @Value("${privateKey}")
  private String privateKey;

  @Resource private UserClient userClient;

  @Autowired private SysProjectService sysProjectService;

  // 属于代发项目
  public static final String DROPSHIPPING_TRUE = "1";

  /**
   * 根据账户获取用户信息，异常则返回null
   *
   * @param account
   * @return
   * @throws InterruptedException
   */
  public SysUser getSysUser(String account) {

    SysUser sysUser = null;
    try {
      boolean flag = redisService.hasKey(RedisKey.SYS_USER_LIST);
      if (flag) {
        sysUser = redisService.getCacheMapValue(RedisKey.SYS_USER_LIST, account, SysUser.class);
        if (!ObjectUtils.isEmpty(sysUser)) {
          return sysUser;
        }
      }
      Object res = userClient.getUserInfoByAccount(account);
      sysUser = RsaUtils.decryptByPrivateKey(res, SysUser.class, privateKey);
    } catch (Exception e) {
      ExceptionUtil.exceptionToString(e);
      return null;
    }
    return sysUser;
  }

  public SysUser getSysUserByUserId(String userId) {

    SysUser sysUser = null;
    try {
      boolean flag = redisService.hasKey(RedisKey.SYS_USER_LIST);
      if (flag) {
        List<SysUser> sysUserList =
            redisService.getCacheList(RedisKey.SYS_USER_LIST, SysUser.class);
        List<SysUser> resultSysUserList =
            sysUserList.stream()
                .filter(
                    u -> {
                      return !ObjectUtils.isEmpty(u) && u.getUserId().equals(userId);
                    })
                .collect(Collectors.toList());
        if (resultSysUserList.size() > 0) {
          return resultSysUserList.get(0);
        }
      }
      Object res = userClient.getSysUserByUserId(userId);
      sysUser = RsaUtils.decryptByPrivateKey(res, SysUser.class, privateKey);
    } catch (Exception e) {
      ExceptionUtil.exceptionToString(e);
      e.printStackTrace();
      return null;
    }
    return sysUser;
  }

  @Override
  public SaResult createProjectHelpLink(ProjectHelpBo projectHelpBo) {

    try {
      String loginId = StpUtil.getLoginId().toString();
      SysUser sysUser = getSysUser(loginId);
      // if (StringUtils.isEmpty(sysUser.getEmail()) ||
      // StringUtils.isEmpty(sysUser.getPhoneNumber())) {
      //     return SaResult.error("请到个人中心设置邮箱和联系方式");
      // }
      // if (!Pattern.matches(RegexPool.EMAIL, sysUser.getEmail())) {
      //     return SaResult.error("请到个人中心设置邮箱和联系方式");
      // }

      // 如果用户的创建剩余次数小于10次，提醒明天再来
      if (sysUser.getCreateProjectHelpTimes() <= 0) {
        return SaResult.error("今日分享好友已上限！").setCode(888);
      }

      // 判断项目中是否有该项目的id
      // 根据前端传递过来的项目id，判断项目列表中是否有该项目
      SysProject sysProject = sysProjectService.getProjectByUUID(projectHelpBo.getPUUID());
      if (ObjectUtils.isEmpty(sysProject)) {
        return SaResult.error("项目不存在或已成交");
      }
      if (sysProject.getStatus() != 1) {
        return SaResult.error("违规操作");
      }
      // 获取项目助力列表
      ProjectHelp duplicateCheck =
          getProjectHelpLink(projectHelpBo.getPUUID(), sysUser.getUserId());

      // 如果之前创建过那么直接返回之前创建过的
      if (duplicateCheck != null) {
        return SaResult.ok().setData(duplicateCheck);
      }

      //  没有创建过，则创建
      ProjectHelp projectHelp =
          ProjectHelp.builder()
              .hpId(UUID.randomUUID().toString())
              .pUUID(sysProject.getUuid())
              .createUserId(sysUser.getUserId())
              .hpNumber(0)
              .pContent(sysProject.getContent())
              .pPrice(sysProject.getPrice())
              .pReleaseUserId(sysProject.getReleaseUserId())
              .hpStatus(0)
              .hpCreateNickName(sysUser.getNickName())
              .ipTerritory(sysUser.getIpTerritory())
              .projectCreateNickName(sysProject.getNickname())
              .projectId(sysProject.getPId())
              .createTime(LocalDateTime.now())
              .name(sysProject.getName())
              .dropshipping(sysProject.getDropshipping())
              .build();
      SourceToTargetUtils.copyNotNullProperties(sysProject,projectHelp);

      // 创建项目助力信息，并同步到缓存
      int insertResult = projectHelpMapper.insert(projectHelp);
      if (insertResult == 0) {
        return SaResult.error("创建失败");
      }
      // 消息队列通知用户服务对该用户的创建次数减一
      sysUser.setCreateProjectHelpTimes(sysUser.getCreateProjectHelpTimes() - 1);
      kafkaSender.send(sysUser, KafKaTopics.UPDATE_USER);
      return SaResult.ok().setData(projectHelp);
    } catch (Exception e) {
      ExceptionUtil.exceptionToString(e);
      e.printStackTrace();
      return SaResult.error("服务器异常");
    }
  }

  @Override
  public SaResult updateProjectHelpNumber(ProjectHelpBo projectHelpBo) {

    try {
      String loginId = StpUtil.getLoginId().toString();
      SysUser sysUser = getSysUser(loginId);
      ProjectHelp projectHelp = getProjectHelpByHpId(projectHelpBo.getHpId());
      if (ObjectUtils.isEmpty(projectHelp)) {
        return SaResult.error("分享链接不存在");
      }
      // 如果项目已经助力成功，那么直接返回好友已经成功
      if (projectHelp.getHpNumber() >= 3 || projectHelp.getHpStatus() == 1) {
        return SaResult.ok("助力成功");
      }
      if (projectHelp.getCreateUserId().equals(sysUser.getUserId())) {
        return SaResult.error("请分享给好友");
      }
      if (sysUser.getProjectHelpTimes() <= 0) {
        return SaResult.error("今日助力次数上限");
      }
      //  用户的助力次数减少一，返回助力成功
      sysUser.setProjectHelpTimes(sysUser.getProjectHelpTimes() - 1);
      kafkaSender.send(sysUser, KafKaTopics.UPDATE_USER);
      // 修改项目助力次数,并同步到缓存中
      projectHelp.setHpNumber(projectHelp.getHpNumber() + 1);
      int updateResult = this.updateProjectHelp(projectHelp);
      if (updateResult == 0) {
        log.error("项目助力失败,hpId:{}" + projectHelpBo.getHpId());
        return SaResult.error("服务器繁忙");
      }
      // 如果项目助力值大于等于10，邮件通知
      // if (projectHelp.getHpNumber() >= 10) {
      //   SysUser createSysUser = this.getSysUserByUserId(projectHelp.getCreateUserId());
      //   ReceiveEmailBo receiveEmailBo =
      //       ReceiveEmailBo.builder()
      //           .receiverEmail(createSysUser.getEmail())
      //           .title("spaceObj")
      //           .content("项目：" + projectHelp.getPContent().substring(0, 10) + "... 助力成功！快去联系吧！")
      //           .build();
      //   kafkaSender.send(receiveEmailBo, KafKaTopics.HELP_PROJECT_SUCCESSFUL);
      // }
      return SaResult.ok("助力成功");
    } catch (Exception e) {
      ExceptionUtil.exceptionToString(e);
      e.printStackTrace();
      return SaResult.error("服务器异常");
    }
  }

  @Override
  public int updateProjectHelp(ProjectHelp projectHelp) {

    QueryWrapper<ProjectHelp> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("hp_id", projectHelp.getHpId());
    int result = projectHelpMapper.update(projectHelp, queryWrapper);
    return result;
  }

  @Override
  public ProjectHelp getProjectHelpLink(String pUUID, String userId) {

    ProjectHelp projectHelp = null;
    try {
      QueryWrapper<ProjectHelp> queryWrapper = new QueryWrapper<>();
      queryWrapper.eq("p_uuid", pUUID);
      queryWrapper.eq("create_user_id", userId);
      projectHelp = projectHelpMapper.selectOne(queryWrapper);
    } catch (Exception e) {
      ExceptionUtil.exceptionToString(e);
      e.printStackTrace();
      //  程序异常
      return null;
    }

    return projectHelp;
  }

  @Override
  public List<ProjectHelp> list(ProjectHelp projectHelp) {
    QueryWrapper<ProjectHelp> queryWrap = new QueryWrapper<>();
    return projectHelpMapper.selectList(queryWrap);
  }

  @Override
  public SaResult projectHelpList(ProjectHelpBo projectHelpBo) {

    List<ProjectHelp> list = new ArrayList<>();
    ;
    try {
      String loginId = StpUtil.getLoginId().toString();
      SysUser sysUser = getSysUser(loginId);

      QueryWrapper<ProjectHelp> queryWrapper = new QueryWrapper<>();

      queryWrapper.eq("create_user_id", sysUser.getUserId());
      queryWrapper.orderByDesc("create_time");

      Page<ProjectHelp> page =
          new Page<>(projectHelpBo.getCurrentPage(), projectHelpBo.getPageSize());
      IPage<ProjectHelp> iPage = projectHelpMapper.selectPage(page, queryWrapper);
      list = iPage.getRecords();
      return SaResult.ok().setData(list);
    } catch (Exception e) {
      ExceptionUtil.exceptionToString(e);
      e.printStackTrace();
      return SaResult.error("服务器异常");
    }
  }

  @Override
  public ProjectHelp getProjectHelpByHpId(String hpId) {

    ProjectHelp projectHelp = null;

    QueryWrapper<ProjectHelp> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("hp_id", hpId);

    try {
      projectHelp = projectHelpMapper.selectOne(queryWrapper);
    } catch (Exception e) {
      ExceptionUtil.exceptionToString(e);
      e.printStackTrace();
      return null;
    }

    return projectHelp;
  }
}
